import React, { useState, useEffect, useCallback, useRef } from 'react';
import { Card, CardContent, CardHeader, CardTitle } from './ui/card';
import { Button } from './ui/button';
import { Progress } from './ui/progress';
import { Badge } from './ui/badge';
import { Eye, Timer, Target, RotateCcw, Zap, AlertCircle } from 'lucide-react';
import { TestResult } from '../types';

interface AttentionTestProps {
  onComplete: (result: TestResult) => void;
}

type TestState = 'ready' | 'testing' | 'complete';

interface Stimulus {
  id: number;
  x: number;
  y: number;
  isTarget: boolean;
  clicked: boolean;
  isCorrect?: boolean;
  timeoutId?: NodeJS.Timeout;
}

export function AttentionTest({ onComplete }: AttentionTestProps) {
  const [state, setState] = useState<TestState>('ready');
  const [stimuli, setStimuli] = useState<Stimulus[]>([]);
  const [timeLeft, setTimeLeft] = useState(30);
  const [score, setScore] = useState({ correct: 0, incorrect: 0, missed: 0 });
  const [currentStimulus, setCurrentStimulus] = useState<Stimulus | null>(null);
  const [testStartTime, setTestStartTime] = useState<number>(0);
  
  // 测试完成时的数据快照，防止数据不一致
  const [finalSnapshot, setFinalSnapshot] = useState<{
    finalScore: number;
    accuracy: number;
    responsiveness: number;
    totalTestTime: number;
    totalTargets: number;
    totalNonTargets: number;
    score: { correct: number; incorrect: number; missed: number };
    stimuli: Stimulus[];
    rating: { text: string; color: string };
  } | null>(null);
  
  // 使用 refs 管理定时器，避免状态更新导致的重新渲染问题
  const gameIntervalRef = useRef<NodeJS.Timeout | null>(null);
  const timerIntervalRef = useRef<NodeJS.Timeout | null>(null);
  const allTimeoutsRef = useRef<Set<NodeJS.Timeout>>(new Set());
  const stateRef = useRef<TestState>('ready');

  const testDuration = 30; // seconds
  const stimulusInterval = 1500; // milliseconds
  const stimulusDuration = 1000; // milliseconds
  const targetProbability = 0.3; // 30% chance of target

  // 保持状态 ref 同步
  useEffect(() => {
    stateRef.current = state;
  }, [state]);

  // 清理所有定时器的函数
  const clearAllTimers = useCallback(() => {
    if (gameIntervalRef.current) {
      clearInterval(gameIntervalRef.current);
      gameIntervalRef.current = null;
    }
    if (timerIntervalRef.current) {
      clearInterval(timerIntervalRef.current);
      timerIntervalRef.current = null;
    }
    allTimeoutsRef.current.forEach(timeoutId => clearTimeout(timeoutId));
    allTimeoutsRef.current.clear();
  }, []);

  const generateStimulus = useCallback(() => {
    // 严格检查测试状态 - 只有在 testing 状态下才生成刺激
    if (stateRef.current !== 'testing') return;
    
    const containerWidth = 400;
    const containerHeight = 300;
    const stimulusSize = 60;
    
    const stimulusId = Date.now() + Math.random();
    
    const stimulus: Stimulus = {
      id: stimulusId,
      x: Math.random() * (containerWidth - stimulusSize),
      y: Math.random() * (containerHeight - stimulusSize),
      isTarget: Math.random() < targetProbability,
      clicked: false
    };

    // 设置超时处理
    const timeoutId = setTimeout(() => {
      // 双重检查：状态必须仍为 testing
      if (stateRef.current !== 'testing') {
        allTimeoutsRef.current.delete(timeoutId);
        return;
      }
      
      setCurrentStimulus(prev => prev?.id === stimulus.id ? null : prev);
      
      // 只有在刺激未被点击且是目标时才标记为遗漏
      setStimuli(prev => prev.map(s => {
        if (s.id === stimulus.id && s.isTarget && !s.clicked) {
          // 再次检查状态
          if (stateRef.current === 'testing') {
            setScore(prevScore => ({ ...prevScore, missed: prevScore.missed + 1 }));
          }
          return { ...s, isCorrect: false };
        }
        return s;
      }));
      
      // 从追踪集合中移除已完成的超时
      allTimeoutsRef.current.delete(timeoutId);
    }, stimulusDuration);

    // 追踪所有超时定时器
    allTimeoutsRef.current.add(timeoutId);

    // 将超时ID添加到刺激对象中
    const stimulusWithTimeout = { ...stimulus, timeoutId };
    
    setCurrentStimulus(stimulusWithTimeout);
    setStimuli(prev => [...prev, stimulusWithTimeout]);
  }, []);

  const startTest = useCallback(() => {
    // 清理之前的定时器
    clearAllTimers();
    
    setState('testing');
    setTimeLeft(testDuration);
    setScore({ correct: 0, incorrect: 0, missed: 0 });
    setStimuli([]);
    setCurrentStimulus(null);
    setTestStartTime(Date.now());

    // 延迟启动定时器，确保状态已更新
    setTimeout(() => {
      // Timer
      const timer = setInterval(() => {
        setTimeLeft(prev => {
          if (prev <= 1) {
            clearInterval(timer);
            setState('complete');
            return 0;
          }
          return prev - 1;
        });
      }, 1000);
      timerIntervalRef.current = timer;

      // Generate stimuli
      const game = setInterval(() => {
        generateStimulus();
      }, stimulusInterval);
      gameIntervalRef.current = game;
      
      // Generate first stimulus immediately
      generateStimulus();
    }, 50);
  }, [clearAllTimers, generateStimulus]);

  const handleStimulusClick = (stimulus: Stimulus) => {
    // 严格检查：只有在测试状态下且刺激未被点击时才处理
    if (stateRef.current !== 'testing' || stimulus.clicked) return;

    // 立即清除该刺激的超时定时器，防止竞争条件
    if (stimulus.timeoutId) {
      clearTimeout(stimulus.timeoutId);
      allTimeoutsRef.current.delete(stimulus.timeoutId);
    }

    const isCorrect = stimulus.isTarget;
    
    // 更新刺激状态
    setStimuli(prev => prev.map(s => 
      s.id === stimulus.id 
        ? { ...s, clicked: true, isCorrect, timeoutId: undefined }
        : s
    ));

    // 更新分数
    if (isCorrect) {
      setScore(prev => ({ ...prev, correct: prev.correct + 1 }));
    } else {
      setScore(prev => ({ ...prev, incorrect: prev.incorrect + 1 }));
    }

    // 隐藏当前刺激
    setCurrentStimulus(prev => prev?.id === stimulus.id ? null : prev);
  };

  const resetTest = () => {
    // 使用统一的清理函数
    clearAllTimers();
    
    setState('ready');
    setTimeLeft(testDuration);
    setScore({ correct: 0, incorrect: 0, missed: 0 });
    setStimuli([]);
    setCurrentStimulus(null);
    setTestStartTime(0);
    setFinalSnapshot(null); // 清除数据快照
  };

  const getAccuracy = () => {
    const total = score.correct + score.incorrect + score.missed;
    if (total === 0) return 0;
    const accuracy = (score.correct / total) * 100;
    return Math.round(isNaN(accuracy) ? 0 : Math.max(0, Math.min(100, accuracy)));
  };

  const getReactionSpeed = () => {
    // Calculate based on correct responses and missed targets
    const totalTargets = score.correct + score.missed;
    if (totalTargets === 0) return 0;
    const responsiveness = (score.correct / totalTargets) * 100;
    return Math.round(isNaN(responsiveness) ? 0 : Math.max(0, Math.min(100, responsiveness)));
  };

  const getFinalScore = () => {
    const accuracy = getAccuracy();
    const responsiveness = getReactionSpeed();
    const totalTargets = stimuli.filter(s => s.isTarget).length;
    const completionBonus = totalTargets > 15 ? 10 : 0;
    
    const baseScore = (accuracy * 0.6 + responsiveness * 0.4);
    const finalScore = baseScore + completionBonus;
    return Math.round(isNaN(finalScore) ? 0 : Math.max(0, Math.min(100, finalScore)));
  };

  const getRating = () => {
    const finalScore = getFinalScore();
    if (finalScore >= 90) return { text: '注意力专家', color: 'text-yellow-500' };
    if (finalScore >= 80) return { text: '优秀', color: 'text-green-500' };
    if (finalScore >= 70) return { text: '良好', color: 'text-blue-500' };
    if (finalScore >= 60) return { text: '一般', color: 'text-gray-500' };
    return { text: '需要提高', color: 'text-orange-500' };
  };

  const handleComplete = () => {
    // 使用快照数据，确保数据一致性
    if (!finalSnapshot) return;
    
    const result: TestResult = {
      id: Date.now().toString(),
      testType: 'attention',
      score: finalSnapshot.finalScore,
      completedAt: new Date(),
      duration: Math.max(1, finalSnapshot.totalTestTime),
      details: {
        accuracy: finalSnapshot.accuracy,
        responsiveness: finalSnapshot.responsiveness,
        correctClicks: finalSnapshot.score.correct,
        incorrectClicks: finalSnapshot.score.incorrect,
        missedTargets: finalSnapshot.score.missed,
        totalTargets: finalSnapshot.totalTargets,
        totalNonTargets: finalSnapshot.totalNonTargets,
        totalStimuli: finalSnapshot.stimuli.length,
        rating: finalSnapshot.rating.text,
        testDuration: testDuration,
        
        // 兼容性字段
        totalQuestions: finalSnapshot.stimuli.length,
        correctAnswers: finalSnapshot.score.correct,
        averageTimePerQuestion: finalSnapshot.stimuli.length > 0 ? Math.round(finalSnapshot.totalTestTime / finalSnapshot.stimuli.length) : 0,
        
        // 注意力测试特有字段
        averageTime: finalSnapshot.totalTestTime,
        totalRounds: finalSnapshot.stimuli.length,
        difficulty: 'medium',
        
        // 详细统计
        targetHitRate: finalSnapshot.totalTargets > 0 ? Math.round((finalSnapshot.score.correct / finalSnapshot.totalTargets) * 100) : 0,
        falseAlarmRate: finalSnapshot.totalNonTargets > 0 ? Math.round((finalSnapshot.score.incorrect / finalSnapshot.totalNonTargets) * 100) : 0,
        missRate: finalSnapshot.totalTargets > 0 ? Math.round((finalSnapshot.score.missed / finalSnapshot.totalTargets) * 100) : 0
      }
    };
    onComplete(result);
  };

  // 监听状态变化，当测试完成时立即清理所有定时器并创建数据快照
  useEffect(() => {
    if (state === 'complete' && !finalSnapshot) {
      // 立即清理所有定时器
      clearAllTimers();
      
      // 强制处理所有未完成的刺激，确保数据完整性
      let processedScore = { ...score };
      let processedStimuli = [...stimuli];
      
      // 处理所有未完成的目标刺激（既没有被点击也没有设置 isCorrect 的目标）
      processedStimuli = processedStimuli.map(stimulus => {
        if (stimulus.isTarget && !stimulus.clicked && stimulus.isCorrect === undefined) {
          // 未处理的目标刺激标记为遗漏
          processedScore.missed += 1;
          return { ...stimulus, isCorrect: false };
        }
        return stimulus;
      });
      
      // 处理当前正在显示的刺激
      if (currentStimulus && currentStimulus.isTarget && !currentStimulus.clicked) {
        // 如果当前刺激是目标且未被点击，也标记为遗漏
        const stimulusExists = processedStimuli.some(s => s.id === currentStimulus.id);
        if (!stimulusExists) {
          processedStimuli.push({ ...currentStimulus, isCorrect: false });
          processedScore.missed += 1;
        }
      }
      
      // 创建数据快照，防止后续异步操作影响数据
      const currentTestTime = testStartTime > 0 ? Math.round((Date.now() - testStartTime) / 1000) : testDuration;
      const allTargetStimuli = processedStimuli.filter(s => s.isTarget);
      const allNonTargetStimuli = processedStimuli.filter(s => !s.isTarget);
      
      // 验证数据一致性：确保 correct + missed = 总目标数
      const actualTargetCount = allTargetStimuli.length;
      const processedTargetCount = processedScore.correct + processedScore.missed;
      
      // 如果还有差异，说明有目标刺激没有被正确统计，补齐遗漏数
      if (actualTargetCount > processedTargetCount) {
        const missingTargets = actualTargetCount - processedTargetCount;
        processedScore.missed += missingTargets;
      }
      
      // 计算最终指标 - 使用处理后的数据
      const total = processedScore.correct + processedScore.incorrect + processedScore.missed;
      const accuracy = total === 0 ? 0 : Math.round(Math.max(0, Math.min(100, (processedScore.correct / total) * 100)));
      const totalTargets = processedScore.correct + processedScore.missed;
      const responsiveness = totalTargets === 0 ? 0 : Math.round(Math.max(0, Math.min(100, (processedScore.correct / totalTargets) * 100)));
      const completionBonus = actualTargetCount > 15 ? 10 : 0;
      const baseScore = (accuracy * 0.6 + responsiveness * 0.4);
      const finalScore = Math.round(Math.max(0, Math.min(100, baseScore + completionBonus)));
      
      // 确定评级
      let rating;
      if (finalScore >= 90) rating = { text: '注意力专家', color: 'text-yellow-500' };
      else if (finalScore >= 80) rating = { text: '优秀', color: 'text-green-500' };
      else if (finalScore >= 70) rating = { text: '良好', color: 'text-blue-500' };
      else if (finalScore >= 60) rating = { text: '一般', color: 'text-gray-500' };
      else rating = { text: '需要提高', color: 'text-orange-500' };
      
      // 创建不可变的数据快照 - 使用验证后的数据
      setFinalSnapshot({
        finalScore,
        accuracy,
        responsiveness,
        totalTestTime: currentTestTime,
        totalTargets: actualTargetCount,  // 使用实际目标数
        totalNonTargets: allNonTargetStimuli.length,
        score: processedScore,  // 使用处理后的分数
        stimuli: processedStimuli,  // 使用处理后的刺激列表
        rating
      });
      
      // 更新状态以反映最终的处理结果
      setScore(processedScore);
      setStimuli(processedStimuli);
    }
  }, [state, clearAllTimers, finalSnapshot, score, stimuli, currentStimulus, testStartTime, testDuration]);

  // 组件卸载时清理
  useEffect(() => {
    return () => {
      clearAllTimers();
    };
  }, [clearAllTimers]);

  if (state === 'complete' && finalSnapshot) {
    return (
      <div className="max-w-2xl mx-auto space-y-6">
        <Card>
          <CardHeader className="text-center">
            <CardTitle className="flex items-center justify-center gap-2">
              <Eye className="w-6 h-6 text-green-500" />
              测试完成！
            </CardTitle>
          </CardHeader>
          <CardContent className="space-y-6">
            <div className="text-center space-y-4">
              <div className="text-6xl font-bold text-primary">
                {finalSnapshot.finalScore}
              </div>
              <div className={`text-xl font-semibold ${finalSnapshot.rating.color}`}>
                {finalSnapshot.rating.text}
              </div>
            </div>

            <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
              <div className="text-center p-4 bg-green-50 dark:bg-green-950 rounded-lg">
                <div className="text-2xl font-bold text-green-600">{finalSnapshot.score.correct}</div>
                <div className="text-sm text-muted-foreground">正确点击</div>
              </div>
              <div className="text-center p-4 bg-red-50 dark:bg-red-950 rounded-lg">
                <div className="text-2xl font-bold text-red-600">{finalSnapshot.score.incorrect}</div>
                <div className="text-sm text-muted-foreground">错误点击</div>
              </div>
              <div className="text-center p-4 bg-orange-50 dark:bg-orange-950 rounded-lg">
                <div className="text-2xl font-bold text-orange-600">{finalSnapshot.score.missed}</div>
                <div className="text-sm text-muted-foreground">遗漏目标</div>
              </div>
              <div className="text-center p-4 bg-blue-50 dark:bg-blue-950 rounded-lg">
                <div className="text-2xl font-bold text-blue-600">{finalSnapshot.accuracy}%</div>
                <div className="text-sm text-muted-foreground">准确率</div>
              </div>
            </div>

            <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
              <div className="text-center p-4 bg-muted rounded-lg">
                <div className="text-xl font-bold">{finalSnapshot.totalTargets}</div>
                <div className="text-sm text-muted-foreground">总目标数</div>
                <div className="text-xs text-muted-foreground mt-1">
                  验证: {finalSnapshot.score.correct + finalSnapshot.score.missed}
                </div>
              </div>
              <div className="text-center p-4 bg-muted rounded-lg">
                <div className="text-xl font-bold">{finalSnapshot.totalNonTargets}</div>
                <div className="text-sm text-muted-foreground">干扰项数</div>
                <div className="text-xs text-muted-foreground mt-1">
                  总刺激: {finalSnapshot.stimuli.length}
                </div>
              </div>
              <div className="text-center p-4 bg-muted rounded-lg">
                <div className="text-xl font-bold">{finalSnapshot.responsiveness}%</div>
                <div className="text-sm text-muted-foreground">反应性评分</div>
                <div className="text-xs text-muted-foreground mt-1">
                  目标命中率
                </div>
              </div>
            </div>

            <div className="flex gap-4">
              <Button 
                onClick={resetTest} 
                variant="outline" 
                className="flex-1 border-2 border-slate-300 hover:border-green-500 hover:bg-green-50 hover:text-green-700 transition-all duration-200"
              >
                <RotateCcw className="w-4 h-4 mr-2" />
                重新测试
              </Button>
              <Button 
                onClick={handleComplete} 
                className="flex-1 bg-gradient-to-r from-green-500 to-emerald-500 text-white hover:from-green-600 hover:to-emerald-600 shadow-md hover:shadow-lg transition-all duration-200"
              >
                保存结果
              </Button>
            </div>
          </CardContent>
        </Card>
      </div>
    );
  }

  return (
    <div className="max-w-2xl mx-auto space-y-6">
      {state === 'testing' && (
        <Card>
          <CardContent className="pt-6">
            <div className="flex justify-between items-center mb-4">
              <div className="flex items-center gap-4">
                <div className="flex items-center gap-2">
                  <Timer className="w-4 h-4" />
                  <span className="font-mono text-lg">{timeLeft}s</span>
                </div>
                <Badge variant={timeLeft > 20 ? 'secondary' : timeLeft > 10 ? 'default' : 'destructive'}>
                  {timeLeft > 20 ? '充足时间' : timeLeft > 10 ? '注意时间' : '时间紧急'}
                </Badge>
              </div>
              <div className="flex items-center gap-4">
                <div className="text-sm text-green-600">
                  <Target className="w-4 h-4 inline mr-1" />
                  {score.correct}
                </div>
                <div className="text-sm text-red-600">
                  <AlertCircle className="w-4 h-4 inline mr-1" />
                  {score.incorrect}
                </div>
                <div className="text-sm text-orange-600">
                  <Zap className="w-4 h-4 inline mr-1" />
                  {score.missed}
                </div>
              </div>
            </div>
            <Progress value={((testDuration - timeLeft) / testDuration) * 100} />
          </CardContent>
        </Card>
      )}

      <Card>
        {state === 'ready' && (
          <>
            <CardHeader className="text-center">
              <CardTitle className="flex items-center justify-center gap-2">
                <Eye className="w-6 h-6 text-green-500" />
                注意力测试
              </CardTitle>
            </CardHeader>
            <CardContent className="space-y-6">
              <div className="text-center space-y-4">
                <p className="text-muted-foreground">
                  在 {testDuration} 秒内，只点击蓝色的目标圆圈，忽略灰色的干扰项。
                </p>
                <div className="flex justify-center gap-4">
                  <div className="flex items-center gap-2">
                    <div className="w-6 h-6 bg-blue-500 rounded-full"></div>
                    <span className="text-sm">目标 - 点击</span>
                  </div>
                  <div className="flex items-center gap-2">
                    <div className="w-6 h-6 bg-gray-400 rounded-full"></div>
                    <span className="text-sm">干扰 - 忽略</span>
                  </div>
                </div>
              </div>
              <div className="text-center">
                <Button 
                  size="lg" 
                  onClick={startTest}
                  className="bg-gradient-to-r from-slate-400 to-gray-500 hover:from-slate-500 hover:to-gray-600 text-white shadow-lg hover:shadow-xl transform hover:scale-105 transition-all duration-300 border-0 min-w-[140px] h-12"
                >
                  <Eye className="w-5 h-5 mr-2" />
                  开始测试
                </Button>
              </div>
            </CardContent>
          </>
        )}

        {state === 'testing' && (
          <CardContent>
            <div className="relative w-full h-80 bg-muted rounded-lg overflow-hidden">
              {/* Test Area */}
              <div className="absolute inset-4">
                {currentStimulus && (
                  <div
                    className={`absolute w-15 h-15 rounded-full cursor-pointer transition-all duration-200 hover:scale-110 ${
                      currentStimulus.isTarget 
                        ? 'bg-blue-500 hover:bg-blue-600' 
                        : 'bg-gray-400 hover:bg-gray-500'
                    }`}
                    style={{
                      left: currentStimulus.x,
                      top: currentStimulus.y,
                      width: '60px',
                      height: '60px'
                    }}
                    onClick={() => handleStimulusClick(currentStimulus)}
                  />
                )}
              </div>

              {/* Instructions overlay */}
              <div className="absolute top-4 left-4 right-4 text-center">
                <p className="text-sm text-muted-foreground bg-background/80 px-3 py-1 rounded">
                  只点击蓝色圆圈，忽略灰色圆圈
                </p>
              </div>
            </div>

            {/* Real-time stats */}
            <div className="grid grid-cols-4 gap-4 mt-4">
              <div className="text-center p-3 bg-green-50 dark:bg-green-950 rounded-lg">
                <div className="text-lg font-bold text-green-600">{score.correct}</div>
                <div className="text-xs text-muted-foreground">正确</div>
              </div>
              <div className="text-center p-3 bg-red-50 dark:bg-red-950 rounded-lg">
                <div className="text-lg font-bold text-red-600">{score.incorrect}</div>
                <div className="text-xs text-muted-foreground">错误</div>
              </div>
              <div className="text-center p-3 bg-orange-50 dark:bg-orange-950 rounded-lg">
                <div className="text-lg font-bold text-orange-600">{score.missed}</div>
                <div className="text-xs text-muted-foreground">遗漏</div>
              </div>
              <div className="text-center p-3 bg-blue-50 dark:bg-blue-950 rounded-lg">
                <div className="text-lg font-bold text-blue-600">{getAccuracy()}%</div>
                <div className="text-xs text-muted-foreground">准确率</div>
              </div>
            </div>
            
            {/* Debug info for testing */}
            <div className="mt-2 text-xs text-muted-foreground text-center">
              目标数: {stimuli.filter(s => s.isTarget).length} | 
              已处理: {score.correct + score.missed} | 
              总刺激: {stimuli.length}
            </div>
          </CardContent>
        )}
      </Card>

      <Card>
        <CardContent className="pt-6">
          <h3 className="font-semibold mb-2">测试说明</h3>
          <ul className="text-sm text-muted-foreground space-y-1">
            <li>• 测试时长为 {testDuration} 秒</li>
            <li>• 只点击蓝色圆圈（目标）</li>
            <li>• 不要点击灰色圆圈（干扰项）</li>
            <li>• 圆圈会随机出现并在1秒后消失</li>
            <li>• 错过目标或错误点击都会影响得分</li>
          </ul>
        </CardContent>
      </Card>
    </div>
  );
}